package com.five.monkey.feign.es.service.impl;

import com.five.monkey.feign.es.convert.CardConvert;
import com.five.monkey.feign.es.convert.PageConvert;
import com.five.monkey.feign.es.dao.model.Card;
import com.five.monkey.feign.es.dao.repository.CardRepository;
import com.five.monkey.feign.es.service.CardElasticsearchService;
import com.five.monkey.vo.CardVo;
import com.five.monkey.vo.PageVo;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.common.unit.TimeValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 狻猊
 * @date 2022-03-29 14:41:36
 */
@Service
public class CardElasticsearchServiceImpl implements CardElasticsearchService {

    private static final Logger logger = LoggerFactory.getLogger(CardElasticsearchServiceImpl.class);

    @Autowired
    private ElasticsearchOperations elasticsearchRestTemplate;

    @Autowired
    private CardRepository cardRepository;

    /**
     * 创建索引
     * @author 狻猊
     * @return boolean
     * @date 2022/3/31 10:19 上午
     */
    @Override
    public boolean createIndex() {
        return elasticsearchRestTemplate.createIndex(Card.class);
    }

    /**
     * 根据content查询卡片信息，按照创建时间倒序分页
     * @author 狻猊
     * @param content 搜索关键词
     * @param pageNum 页码，从1开始
     * @param pageSize 页面大小
     * @return com.five.monkey.vo.PageVo<com.five.monkey.vo.CardVo>
     * @date 2022/3/29 3:53 下午
     */
    @Override
    public PageVo<CardVo> findByContent(String content, int pageNum, int pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize, Sort.by(Sort.Order.desc("createTime")));
        Page<Card> cardPage = cardRepository.findByContentMatches(content, pageable);
        return new PageConvert<Card, CardVo>().page2vo(cardPage, CardConvert::esModel2vo);
    }

    /**
     * 根据content查询卡片信息
     * @author 狻猊
     * @param content 搜索关键词
     * @return java.util.List<com.five.monkey.vo.CardVo>
     * @date 2022/3/29 3:53 下午
     */
    @Override
    public List<CardVo> findByContent(String content) {
        List<Card> cardList = cardRepository.findByContentMatches(content);
        return cardList.stream().map(CardConvert::esModel2vo).collect(Collectors.toList());
    }

    /**
     * 保存（新增或修改）卡片信息
     * @author 狻猊
     * @param vo 卡片信息
     * @return com.five.monkey.vo.CardVo
     * @date 2022/3/29 3:58 下午
     */
    @Override
    public CardVo save(CardVo vo) {
        Card card = CardConvert.vo2esModel(vo);
        if (Objects.isNull(card)) {
            return null;
        }
        card = cardRepository.save(card);
        return CardConvert.esModel2vo(card);
    }

    /**
     * 批量保存（新增或修改）卡片信息
     * @author 狻猊
     * @param cardVoList 卡片信息集合
     * @return java.util.List<com.five.monkey.vo.CardVo>
     * @date 2022/3/31 4:33 下午
     */
    @Override
    public List<CardVo> batchSave(List<CardVo> cardVoList) {
        BulkOptions bulkOptions = BulkOptions.builder().withTimeout(TimeValue.timeValueSeconds(5)).build();
        List<IndexQuery> indexQueryList = Lists.newArrayList();
        for (CardVo cardVo : cardVoList) {
            Card card = CardConvert.vo2esModel(cardVo);
            if (Objects.isNull(card)) {
                continue;
            }
            cardVo.setCreateTime(card.getCreateTime());
            IndexQuery indexQuery = new IndexQuery();
            indexQuery.setIndexName("t_card");
            indexQuery.setId(card.getId().toString());
            indexQuery.setObject(card);
            indexQueryList.add(indexQuery);
            if (indexQueryList.size() >= 500) {
                elasticsearchRestTemplate.bulkIndex(indexQueryList, bulkOptions);
                indexQueryList.clear();
            }
        }
        if (CollectionUtils.isNotEmpty(indexQueryList)) {
            elasticsearchRestTemplate.bulkIndex(indexQueryList, bulkOptions);
        }
        return cardVoList;
    }

    /**
     * 根据id查询卡片信息
     * @author 狻猊
     * @param id 卡片id
     * @return com.five.monkey.vo.CardVo
     * @date 2022/3/30 12:05 下午
     */
    @Override
    public CardVo findById(Long id) {
        Card card = cardRepository.findById(id).orElse(null);
        return CardConvert.esModel2vo(card);
    }

    /**
     * 根据status查询卡片信息
     * @author 狻猊
     * @param status 卡片状态
     * @return java.util.List<com.five.monkey.vo.CardVo>
     * @date 2022/3/30 12:05 下午
     */
    @Override
    public List<CardVo> findByStatus(int status) {
        List<Card> cardList = cardRepository.findByStatusGreaterThanEqual(status);
        return cardList.stream().map(CardConvert::esModel2vo).collect(Collectors.toList());
    }

    /**
     * 根据adminId查询卡片信息
     * @author 狻猊
     * @param adminId 卡片创建人id
     * @return java.util.List<com.five.monkey.vo.CardVo>
     * @date 2022/3/30 12:05 下午
     */
    @Override
    public List<CardVo> findByAdminId(Long adminId) {
        List<Card> cardList = cardRepository.findByAdminId(adminId);
        return cardList.stream().map(CardConvert::esModel2vo).collect(Collectors.toList());
    }

    /**
     * 根据title模糊查询卡片信息
     * @author 狻猊
     * @param title 卡片标题
     * @return java.util.List<com.five.monkey.vo.CardVo>
     * @date 2022/3/30 12:05 下午
     */
    @Override
    public List<CardVo> findByTitle(String title) {
        List<Card> cardList = cardRepository.findByTitleContains(title);
        return cardList.stream().map(CardConvert::esModel2vo).collect(Collectors.toList());
    }

    /**
     * 根据title全等查询卡片信息
     * @author 狻猊
     * @param title 卡片标题
     * @return java.util.List<com.five.monkey.vo.CardVo>
     * @date 2022/3/30 12:05 下午
     */
    @Override
    public List<CardVo> findByTitleEquals(String title) {
        List<Card> cardList = cardRepository.findByTitle(title);
        return cardList.stream().map(CardConvert::esModel2vo).collect(Collectors.toList());
    }
}
